package com.sap.sap_mangers.service.Impl;

import com.sap.sap_mangers.Vo.MessageBoardVo.MessageBoardArticleVo;
import com.sap.sap_mangers.Vo.MessageBoardVo.MessageBoardCommentVo;
import com.sap.sap_mangers.Vo.MessageBoardVo.MessageBoardNewsVo;
import com.sap.sap_mangers.dto.message_board.MessageBoardArticle;
import com.sap.sap_mangers.dto.message_board.MessageBoardPraise;
import com.sap.sap_mangers.dto.message_board.MessageBoardPraiseAndCommentNews;
import com.sap.sap_mangers.dto.user.NoticeDto;
import com.sap.sap_mangers.mapper.MessageBoardMapper;
import com.sap.sap_mangers.service.MessageBoardService;
import com.sap.sap_mangers.service.UserService;
import com.sap.sap_mangers.until.JwtUtil;
import com.sap.sap_mangers.until.SimpleJson;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 谢添
 * 2022/8/19 16:17
 */
@Service
public class MessageBoardServiceImpl implements MessageBoardService {
    @Resource
    private MessageBoardMapper messageBoardMapper;

    @Resource
    private UserService userService;

    @Override
    public SimpleJson createArticle(MessageBoardArticle article) {
        //合理性验证
        if (!StringUtils.hasText(article.getContent())) {
            return new SimpleJson(1, "您的文章有无效内容，发表失败");
        }
        if (!StringUtils.hasText(article.getTitle())) {
            article.setTitle("无标题");
        }
        if (article.getTitle().length() > 128) {
            return new SimpleJson(1, "您的标题字数不能大于128，发表失败");
        }
        if (article.getContent().length() > 2048) {
            return new SimpleJson(1, "您的内容字数不能大于2048，发表失败");
        }

        //创建新文章 --> article 的 id属性会 被设置
        messageBoardMapper.createArticle(article);

        Integer articleId = article.getArticleId();
        //将新文章的信息返回给前端
        MessageBoardArticleVo articleMessage = messageBoardMapper.getArticleTableMessageById(articleId);

        articleMessage.setPraiseStatus(0);
        return new SimpleJson(0, "发表成功", articleMessage);

    }

    @Override
    public SimpleJson updateArticle(MessageBoardArticle article) {
        if (!StringUtils.hasText(article.getTitle())) {
            article.setTitle("无标题");
        }
        if (!StringUtils.hasText(article.getContent()) || article.getContent().length() > 2048) {
            return new SimpleJson(1, "无效内容，请确认字数不超过2048且内容合理");
        }

        //进行修改，如果该文章id的作者不是当前操作用户，则会操作失败,即使返回的是修改成功，也是无效修改
        messageBoardMapper.updateArticle(article);

        MessageBoardArticleVo articleMessage = getMessageBoardArticleAllMessageByArticleId(article.getArticleId(), Integer.parseInt(JwtUtil.getUserForToken()));

        return new SimpleJson(0, "修改成功", articleMessage);
    }

    @Override
    @Transactional
    public SimpleJson createComment(MessageBoardCommentVo commentVo) {
        //合理性验证
        if (!StringUtils.hasText(commentVo.getContent())) {
            return new SimpleJson(1, "无效的评论，请保证评论的字数不大于1024且内容合理", null);
        }
        Long aLong = messageBoardMapper.existArticle(commentVo.getArticleId());
        if (aLong == null || aLong == 0) {
            return new SimpleJson(2, "文章已失效，请稍后再试");
        }
        Date date = new Date();
        //创建一条消息
        MessageBoardPraiseAndCommentNews commentNews = new MessageBoardPraiseAndCommentNews(null, "评论", null, Integer.parseInt(commentVo.getUserId()), date, commentVo.getArticleId());
        //添加到数据库 --> 或得到了newsId
        messageBoardMapper.createPraiseOrCommentNews(commentNews);

        commentVo.setNewsId(commentNews.getNewsId());
        commentVo.setContentCreateTime(date);

        //添加评论到数据库
        messageBoardMapper.createComment(commentVo);

        //修改消息表的comment_id为创建的评论的id
        messageBoardMapper.updatePraiseAndCommentNewsForCommentOrPraiseIdByNewsId(commentVo.getCommentId(), commentNews.getNewsId());

        //将 article表的评论数加一
        messageBoardMapper.updateCommentLenForAddAtArticleTable(commentVo.getArticleId());

        return new SimpleJson(0, commentVo.getCommentId() + "", getMessageBoardArticleAllMessageByArticleId(commentVo.getArticleId(), Integer.parseInt(commentVo.getUserId())));
    }

    @Override
    public MessageBoardArticleVo getMessageBoardArticleAllMessageByArticleId(Integer articleId, Integer userId) {
        MessageBoardArticleVo articleMessage = messageBoardMapper.getArticleTableMessageById(articleId);
        if (articleMessage == null) {
            return null;
        }
        articleMessage.setMessageBoardCommentVos(messageBoardMapper.getMessageBoardCommentVosByArticleId(articleId));
        articleMessage.setSimplePraiseUsers(messageBoardMapper.getSimplePraiseUsersByArticleId(articleId));
        articleMessage.setPraiseStatus(getPraiseStatusOfArticle(articleId, userId));
        return articleMessage;
    }

    @Override
    @Transactional
    public SimpleJson delComment(MessageBoardCommentVo commentVo) {
        if (commentVo.getCommentId() == null || commentVo.getArticleId() == null) {
            return new SimpleJson(1, "请提供完整信息，删除失败");
        }
        Long aLong = messageBoardMapper.existCommentByCommentIdAndArticleIdAndUserId(commentVo);
        if (aLong == null || aLong == 0) {
            return new SimpleJson(2, "错误的关联信息匹配");
        }
        messageBoardMapper.delCommentByCommentId(commentVo.getCommentId());
        messageBoardMapper.delNewsByCommentOrPraiseId(commentVo.getCommentId());
        messageBoardMapper.reduceCommentLenForArticleTableByArticleId(commentVo.getArticleId());

        return new SimpleJson(0, "删除成功", getMessageBoardArticleAllMessageByArticleId(commentVo.getArticleId(), Integer.parseInt(commentVo.getUserId())));
    }

    @Override
    public SimpleJson getUserAllArticleByUserId(Integer userId) {
        List<MessageBoardArticleVo> messageBoardArticleVos = messageBoardMapper.getUserAllArticleByUserId(userId);
        if (messageBoardArticleVos == null || messageBoardArticleVos.size() == 0) {
            return new SimpleJson(1, "暂未发表任何留言板文章", null);
        }
        //查询所有自己是否为该用户的文章点赞
        int currentUserId = Integer.parseInt(JwtUtil.getUserForToken());
        for (MessageBoardArticleVo messageBoardArticleVo : messageBoardArticleVos) {
            messageBoardArticleVo.setMessageBoardCommentVos(messageBoardMapper.getMessageBoardCommentVosByArticleId(messageBoardArticleVo.getArticleId()));
            messageBoardArticleVo.setSimplePraiseUsers(messageBoardMapper.getSimplePraiseUsersByArticleId(messageBoardArticleVo.getArticleId()));
            messageBoardArticleVo.setPraiseStatus(getPraiseStatusOfArticle(messageBoardArticleVo.getArticleId(), currentUserId));
        }

        return new SimpleJson(0, "获取成功", messageBoardArticleVos);
    }

    @Override
    @Transactional
    public void delArticleByArticleIdAndUserId(Integer articleId, Integer userId) {
        //验证文章匹配存在
        Long aLong = messageBoardMapper.existArticleByArticleIdAndUserId(articleId, userId);
        if (aLong == null || aLong == 0) {
            throw new RuntimeException("删除失败，错误的信息匹配");
        }
        messageBoardMapper.delArticleByArticleId(articleId);
        messageBoardMapper.delCommentByArticleId(articleId);
        messageBoardMapper.delNewsByArticleId(articleId);
        messageBoardMapper.delPraiseByArticleId(articleId);
    }

    @Override
    @Transactional
    public Integer createOrUpdatePraiseStatus(Integer articleId, Integer userId) {
        Integer status = messageBoardMapper.getPraiseStatusOfPraiseTable(articleId, userId);
        if (status == null) {
            //说明从未点赞过 --> 现在我们需要去点赞

            Date date = new Date();
            MessageBoardPraiseAndCommentNews praiseNews = new MessageBoardPraiseAndCommentNews(null, "点赞", null, userId, date, articleId);
            //创建点赞消息
            messageBoardMapper.createPraiseOrCommentNews(praiseNews);

            //设置信息
            MessageBoardPraise praise = new MessageBoardPraise();
            praise.setPraiseCreateTime(new Date());
            praise.setArticleId(articleId);
            praise.setUserId(userId);
            praise.setNewsId(praiseNews.getNewsId());

            //将点赞添加到点赞表
            messageBoardMapper.createPraise(praise);

            //在news表设置comment_or_praise_id
            messageBoardMapper.updatePraiseAndCommentNewsForCommentOrPraiseIdByNewsId(praise.getPraiseId(), praise.getNewsId());

            //在article表中增加点赞次数：
            messageBoardMapper.updatePraiseLenForAddAtArticleTable(articleId);

            return praise.getPraiseId();
        } else {
            //说明点过赞

            if (status == 0) {
                //说明点过赞，但是当前取消了点赞  --> 我们需要重新点赞
                messageBoardMapper.updatePraiseStatusForPraiseTable(articleId, 1, userId);
                //在article表中增加点赞次数：
                messageBoardMapper.updatePraiseLenForAddAtArticleTable(articleId);
            } else {
                //说明当前是点赞状态 --> 我们需要取消点赞
                messageBoardMapper.updatePraiseStatusForPraiseTable(articleId, 0, userId);
                //在article表中增加点赞次数：
                messageBoardMapper.reducePraiseLenForArticleTableByArticleId(articleId);
            }
        }
        return null;
    }

    @Override
    public Integer getPraiseStatusOfArticle(Integer articleId, Integer userId) {
        Integer status = messageBoardMapper.getPraiseStatusOfPraiseTable(articleId, userId);
        return status == null || status == 0 ? 0 : 1;
    }

    @Override
    public List<Integer> getPraiseStatusAndLenOfArticle(Integer articleId, Integer userId) {
        ArrayList<Integer> values = new ArrayList<>();
        values.add(getPraiseStatusOfArticle(articleId, userId));
        values.add(messageBoardMapper.getArticleTableMessageById(articleId).getPraiseLen());
        return values;
    }

    @Override
    public SimpleJson getNewNoViewArticleCounts(Integer userId) {
        return new SimpleJson(0, "获取新文章数量成功", messageBoardMapper.getNewNoViewArticleCounts(userId));
    }

    @Override
    public void updateViewBoardLastTime(Integer userId) {
        messageBoardMapper.updateViewBoardLastTime(userId);
    }

    @Override
    public void updateViewNewsLastTime(Integer userId) {
        messageBoardMapper.updateViewNewsLastTime(userId);
    }

    @Override
    public SimpleJson getArticlesForLimitNumberByArticleId(Integer articleId, Integer limitNumber) {
        List<MessageBoardArticleVo> articles = messageBoardMapper.getArticlesForLimitNumberByArticleId(articleId, limitNumber);
        if (articles == null || articles.size() == 0) {
            return new SimpleJson(1, "暂无更多数据，已经到底了哦~");
        }
        int currentUserId = Integer.parseInt(JwtUtil.getUserForToken());
        for (MessageBoardArticleVo article : articles) {
            article.setMessageBoardCommentVos(messageBoardMapper.getMessageBoardCommentVosByArticleId(article.getArticleId()));
            article.setSimplePraiseUsers(messageBoardMapper.getSimplePraiseUsersByArticleId(article.getArticleId()));
            article.setPraiseStatus(getPraiseStatusOfArticle(article.getArticleId(), currentUserId));
        }
        return new SimpleJson(0, "获取成功", articles);
    }

    @Override
    public SimpleJson getLastTimeViewBoardAndNews(Integer userId) {
        return new SimpleJson(0, "获取最后时间成功", messageBoardMapper.getLastTimeViewBoardAndNews(userId));
    }

    @Override
    public SimpleJson getNoViewNewsNumberForUser(Integer userId) {
        return new SimpleJson(0, "新消息获取成功", messageBoardMapper.getNoViewNewsNumberForUser(userId));
    }

    @Override
    public SimpleJson getNewsForLimitNumber(Integer userId, Integer limitNumber, Integer newsId) {
        List<MessageBoardNewsVo> news = messageBoardMapper.getNewsForLimitNumber(userId, limitNumber, newsId);
        if (news == null || news.size() == 0) {
            return new SimpleJson(1, "暂无更多数据，已经到底了哦~");
        }
        return new SimpleJson(0, "获取成功", news);
    }

    @Override
    public SimpleJson getArticleAllMessage(Integer articleId) {
        messageBoardMapper.updateHitLenForAddAtArticleTable(articleId);
        MessageBoardArticleVo article = getMessageBoardArticleAllMessageByArticleId(articleId, Integer.parseInt(JwtUtil.getUserForToken()));
        if (article == null) {
            return new SimpleJson(1, "错误：文章可能不存在，请稍后再试");
        }
        return new SimpleJson(0, "获取成功", article);
    }

    @Override
    @Transactional
    public void commentNewToNotice(MessageBoardCommentVo messageBoardComment) {
        MessageBoardArticle article = messageBoardMapper.getArticleMessageByArticleId(messageBoardComment.getArticleId());
        String author = article.getUserId();
        List<String> usernameBeforeThisUserToNewNotice = messageBoardMapper.getUsernameBeforeThisUserToNewNotice(messageBoardComment.getContentCreateTime(), messageBoardComment.getArticleId(), messageBoardComment.getUserId() + "");
        if (!(messageBoardComment.getUserId() + "").equals(author) && !usernameBeforeThisUserToNewNotice.contains(author)) {
            usernameBeforeThisUserToNewNotice.add(messageBoardComment.getUserId() + "");
        }
        String realName = userService.getRealName(messageBoardComment.getUserId() + "");
        if (article.getContent().length() >= 20) {
            article.setContent(article.getContent().substring(0, 19) + "...");
        }
        if (messageBoardComment.getContent().length() >= 20) {
            messageBoardComment.setContent(messageBoardComment.getContent().substring(0, 19) + "...");
        }
        for (String username : usernameBeforeThisUserToNewNotice) {
            userService.sendNoticeAuto(new NoticeDto(username, "【评论】" + "关于文章\"" + article.getContent() + "\",用户 " + realName + " 发表评论：" + messageBoardComment.getContent(), null));
        }
    }

    @Override
    @Transactional
    public void praiseNewToNotice(MessageBoardPraise messageBoardPraise) {
        MessageBoardArticle article = messageBoardMapper.getArticleMessageByArticleId(messageBoardPraise.getArticleId());
        String author = article.getUserId();
        List<String> usernameBeforeThisUserToNewNotice = messageBoardMapper.getUsernameBeforeThisUserToNewNotice(messageBoardPraise.getPraiseCreateTime(), messageBoardPraise.getArticleId(), messageBoardPraise.getUserId() + "");
        if (!(messageBoardPraise.getUserId() + "").equals(author) && !usernameBeforeThisUserToNewNotice.contains(author)) {
            usernameBeforeThisUserToNewNotice.add(messageBoardPraise.getUserId() + "");
        }
        String realName = userService.getRealName(messageBoardPraise.getUserId() + "");
        if (article.getContent().length() >= 20) {
            article.setContent(article.getContent().substring(0, 19) + "...");
        }
        for (String username : usernameBeforeThisUserToNewNotice) {
            userService.sendNoticeAuto(new NoticeDto(username, "【点赞】" + "用户 " + realName + " 点赞文章：" + article.getContent() + "", null));
        }
    }

    @Override
    public MessageBoardPraise getPraiseMessageByPraiseId(Integer praiseId) {
        return messageBoardMapper.getPraiseMessageByPraiseId(praiseId);
    }

    @Override
    public MessageBoardCommentVo getCommentMessageByCommentId(Integer commentId) {
        return messageBoardMapper.getCommentMessageByCommentId(commentId);
    }
}
